import React, { useState } from 'react'
import { fromWei } from '../../utils/calculate'
import ERC20 from './abi/ERC20.json'
import ERC165 from './abi/ERC165.json'
import ERC721 from './abi/ERC721.json'
import ERC1155 from './abi/ERC1155.json'
import axios from 'axios'

export default function Contract({ walletInfo, setTextVal, setTextVal2, setCover }) {
    const [tokenVal, setTokenVal] = useState('')
    const [tokenId, setTokenId] = useState('')
    const [tokenValIsCT, setTokenValIsCT] = useState(false)
    const [nftType, setNftType] = useState(null)

    const handelClickCheckToken = async () => {
        const web3 = walletInfo.web3
        console.log(web3)
        try {
            const code = await web3.eth.getCode(tokenVal)
            if (code === '0x') {
                setTextVal('你当前输入的是一个用户地址或未部署的合约地址')
            } else {
                setTokenValIsCT(true)
                setTextVal('你当前输入的是一个TOKEN 合约地址，可进一步判断')
            }
        } catch (error) {
            setTextVal('你当前输入的不是一个合法的地址，请重新校验')
        }
    }

    const handelClickCheckCT = async () => {
        const web3 = walletInfo.web3
        try {
            const CT_20 = await new web3.eth.Contract(ERC20.abi, tokenVal)
            const decimals = await CT_20.methods.decimals().call()
            if (decimals) {
                const name = await CT_20.methods.name().call()
                const symbol = await CT_20.methods.symbol().call()
                const decimals = await CT_20.methods.decimals().call()
                const totalSupply = await CT_20.methods.totalSupply().call()
                let balance = await CT_20.methods.balanceOf(walletInfo.account).call()
                balance = fromWei(balance, decimals)
                setTextVal(`TOKEN地址：${tokenVal}   
    名称：${name}   类型：ERC20     符号：${symbol}     精度：${decimals}    
    发行量：${totalSupply}      持有量：${balance}`)
            }
        } catch (error) {
            const CT_165 = await new web3.eth.Contract(ERC165.abi, tokenVal)
            const isERC721 = await CT_165.methods.supportsInterface('0x80ac58cd').call()
            const isERC1155 = await CT_165.methods.supportsInterface('0xd9b67a26').call()
            if (isERC721) {
                const CT_721 = await new web3.eth.Contract(ERC721.abi, tokenVal)
                const name = await CT_721.methods.name().call()
                const symbol = await CT_721.methods.symbol().call()
                const totalSupply = await CT_721.methods.totalSupply().call()
                const balanceOf = await CT_721.methods.balanceOf(walletInfo.account).call()
                setTextVal(`TOKEN地址：${tokenVal}   
    名称：${name}    类型：ERC721    符号：${symbol}    持有量：${balanceOf}
    发行量：${totalSupply}`)
                setNftType('ERC721')
                setTextVal2(`你输入的是一个NFT地址，请输入TokenID 后点击查询详细信息！`)
            } else if (isERC1155) {
                const CT_1155 = await new web3.eth.Contract(ERC1155.abi, tokenVal)
                console.log(CT_1155)
                setTextVal(`TOKEN地址：${tokenVal}
    类型：ERC1155`)
                setTextVal2(`你输入的是一个NFT地址，请输入TokenID 后点击查询详细信息！`)
                setNftType('ERC1155')
            } else {
                setTextVal(`TOKEN地址：${tokenVal}
    类型：无法查询到TOKEN 信息（非721/1155 代币）`)
            }

        }
    }

    const handelClickShowNFT = async () => {
        const web3 = walletInfo.web3
        if (nftType === 'ERC721') {
            const CT_721 = await new web3.eth.Contract(ERC721.abi, tokenVal)
            const owner = await CT_721.methods.ownerOf(tokenId).call()
            const tokenURI = await CT_721.methods.tokenURI(tokenId).call()
            const res = await axios.get(tokenURI)
            const data = res.data
            const cover = data.properties.image.description
            setTextVal2(`Token ID：${tokenId}    当前持有者：${owner}
    TokenURL: ${tokenURI}
    Title: ${data.title}    Name: ${data.properties.name.description}
    Description: ${data.properties.description.description}
            `)

            setCover(cover)
        } else if (nftType === 'ERC1155') {
            const CT_1155 = await new web3.eth.Contract(ERC1155.abi, tokenVal)
            const balance = await CT_1155.methods.balanceOf(walletInfo.account, tokenId).call()
            const uri = await CT_1155.methods.uri(tokenId).call()
            const res = await axios.get(uri)
            const data = res.data
            const cover = data.properties.image.description
            console.log(CT_1155)
            setTextVal2(`Token ID：${tokenId}    持有量：${balance}
    TokenURL: ${uri}
    Title: ${data.title}    Name: ${data.properties.name.description}
    Description: ${data.properties.description.description}
            `)

            setCover(cover)
        }
    }

    const handelChangeTokenVal = (e) => {
        const { value } = e.target
        setTokenVal(String(value).trim())
        setTokenValIsCT(false)
        setNftType(null)
        setTextVal2(null)
        setCover(null)
        setTokenId('')
    }

    const handelChangeTokenId = (e) => {
        const { value } = e.target
        setTokenId(String(value).trim())
        setCover(null)
    }

    return (
        <div>
            <h3>代币合约操作：</h3>
            <label htmlFor="token">
                <span>Token 地址：</span>
                <input type="token" value={tokenVal} onChange={handelChangeTokenVal} />
            </label>
            <span>  </span>
            <button onClick={handelClickCheckToken} disabled={tokenVal === '' ? true : false}>检验地址是否合法</button>
            <span>  </span>
            <button onClick={handelClickCheckCT} disabled={!tokenValIsCT}>进一步判断合约</button>
            <br />
            <br />

            <label htmlFor="tokenId">
                <span>TokenID：</span>
                <input type="tokenId" disabled={!nftType} value={tokenId} onChange={handelChangeTokenId} />
            </label>
            <span>  </span>
            <button onClick={handelClickShowNFT} disabled={!nftType}>查看NFT信息</button>
        </div>
    )
}
